home *** CD-ROM | disk | FTP | other *** search
- title CTLT - Control-T Interrupt Handler
- page 66,132
- ;***********************************************************************
- ;
- ; This routine works by trapping every interrupt 9 (KB_INT) generated by
- ; the keyboard and handled by the IBM BIOS, and after return from BIOS,
- ; inspecting the key which was typed and is now present in the keyboard
- ; ring buffer in the BIOS data segment (40h). If it is the user interrupt
- ; character (normally a CTL-T), it is removed from the buffer and a status
- ; message is displayed on the console screen.
- ;
- ; *** N O T E ***
- ; This code depends upon buffer size, organization, and location,
- ; and pointers thereto, in the IBM BIOS data segment. If a different keyboard interrupt
- ; handler is installed (e.g. one that increases buffer size), this code
- ; will probably fail!
- ;
- ; [02-Aug-84] Nelson H.F. Beebe
- ;***********************************************************************
-
- .xlist
- include ascii.inc
- include dos.inc
- .list
-
-
- keyvect segment at 0
- org 9h*4 ; BIOS KB_INT
- keyint label dword
- keyvect ends
-
-
- biosdata segment at 40h
- org 1ah ; See p. A-3 of IBM Tech. Ref. Manual
- buffer_head dw ? ; pointer to head of keyboard buffer
- ; -- address of first available char
- buffer_tail dw ? ; pointer to tail of keyboard buffer
- ; -- address of next empty slot
- ; -- buffer is empty if head=tail
- kb_buffer dw 16 dup (?) ; room for 15 entries
- org $-2
- kb_bufend dw ? ; last word in buffer
- biosdata ends
-
-
- ;***********************************************************************
- ;
- ; INIT_CODE - Code to load and initialize the handler.
- ; Sets up DOS to keep all code before "LASTONE" label safe from
- ; overlaying during system operation.
- ;
- ;***********************************************************************
-
- code segment para
- org 100h ; for .COM file
-
- assume cs:code,ds:code,ss:code
- assume es:biosdata
-
- KEY PROC FAR
- start:
- jmp init_code ; done only once at startup
-
- key_call: ; Far JMP to keyboard interrupt
- db 0eah
- dw 0,0
-
- test_msg db "Control-T typed",0
-
- key_rtne:
- sti ; turn interrupts back on
-
- push ax ; save registers
- push bx
- push cx
- push dx
- push bp
- push ds
- push es
- push di
- push si
-
- mov bx,cs
- mov ds,bx ; establish local DS = CS
-
- mov bx,biosdata
- mov es,bx ; establish ES -> BIOSDATA
-
- ; first call original KB_INT BIOS code to actually retrieve the character
- ; over the keyboard port and do its massive amount of bookkeeping
-
- pushf ; IBM keyboard proc expects interrupt
- ; call
- mov bx,offset key_call+1 ; get address of ROM code for keyboard
- call dword ptr [bx] ; call ROM code
-
- ;-----------------------------------------------------------------------
- ; enter critical section -- no interrupts allowed until character retrieved
- ; and buffer pointers updated
-
- cli ; interrupts off while char retrieved
- mov bx,es:buffer_tail ; next available slot in buffer
- dec bx ; backup 2 bytes
- dec bx
- cmp bx,offset kb_buffer ; backed up before start?
- jae nowrap ; no
- mov bx,offset kb_bufend ; yes, move to end of buffer
- nowrap:
- mov ax,es:[bx] ; char in al, scan code in ah
-
- cmp al,.ctlt ; CTL-T?
- jne done ; no
-
- mov es:buffer_tail,bx ; remove last character (the CTL-T)
- sti ; interrupts back on
-
- ; end critical section
- ;-----------------------------------------------------------------------
-
- cld ; set to read string forward
- mov si,offset test_msg ; string to output on CTL-T
-
- mov ah,$video_getvideostate
- int $video ; get current page in bh
-
- mov ah,$video_getattrchar
- int $video ; get current attribute in ah
- mov bl,ah ; save current attribute
-
- msg_loop:
- lodsb ; byte to al, increment si
- mov dl,al ; message byte
- test dl,dl ; byte = 0?
- jz done ; yes, all done
-
- mov ah,$video_settty ; tty output (bl = current attribute)
- int $video ; character
-
- jmp short msg_loop ; keep printing
-
- done:
- sti ; interrupts back on if not yet done
-
- pop si ; restore saved registers
- pop di
- pop es
- pop ds
- pop bp
- pop dx
- pop cx
- pop bx
- pop ax
- iret ; return from interrupt
- KEY ENDP
-
- lastone: ; all code after this label is freed to DOS after
- ; program initialization
-
- copyrt DB 'CONTROL-T Handler -- Version 1.0 -- '
- DB 'Public Domain 1984 -- Nelson H.F. Beebe',13,10,'$'
-
-
- assume cs:code,ds:code,ss:code
- assume es:keyvect ; 'VECTORS' is interrupt segment 0
- INIT_CODE PROC NEAR
-
- ; Initialize KEYBOARD interrupt system
-
- ;-----------------------------------------------------------------------
- ; enter critical section -- no interrupts while adjusting interrupt vector
- ;
- ; cli ; interrupts off
- mov ax,keyvect ; Get address to interrupt vector
- mov es,ax ; Save in ES
- mov ax,es:keyint ; Get address to interrupt routine
- mov bx,offset key_call+1 ; Address to place to save vector
- mov [bx],ax ; Save interrupt address
- mov ax,es:keyint[2] ; Get interrupt segment for routine
- mov [bx+2],ax ; Save it too
- mov es:keyint,offset key_rtne ; Now, replace with own address
- mov ax,cs ; Save segment in interrupt vector
- mov es:keyint[2],ax
- sti ; interrupts back on
-
- ; end critical section
- ;-----------------------------------------------------------------------
-
- ; Now, print out acknowledgement to user monitor and exit
-
- mov ax,cs ; Set up segment to this routine
- mov ds,ax
- mov dx,offset copyrt ; Now, print out copyright message
- mov ah,$DOS_STROUT ; DOS function to print string
- int $DOS ; Execute function interrupt
- mov dx,offset lastone ; Save all code up to "LASTONE" label
- int 27h ; No return needed
-
- INIT_CODE ENDP
- code ends
- end start